package org.study.whitelist;

import com.alibaba.fastjson.JSON;
import org.apache.commons.beanutils.BeanUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.study.whitelist.annotation.DoWhiteList;

import javax.annotation.Resource;
import java.lang.reflect.Method;

/**
 * 定义一个切面
 */
@Aspect
@Component
public class DoJoinPoint {

    @Resource
    private String whiteListConfig;
    // 定义切点
    @Pointcut("@annotation(org.study.whitelist.annotation.DoWhiteList)")
    public void aopPoint() {
    }
    @Around("aopPoint()")
    public Object doRouter(ProceedingJoinPoint jp) throws Throwable {
        System.out.println("进入切面--开始执行切面逻辑");
        Method method =  getMethod(jp);
        DoWhiteList whiteList = method.getAnnotation(DoWhiteList.class);
        // 获取字段值
        String keyValue = getFiledValue(whiteList.key(), jp.getArgs());
        // 如果当前方法没有，就直接往下执行
        if (null == keyValue || "".equals(keyValue)) {
            return jp.proceed();
        }
        // 预先定义好的白名单
        String[] split = whiteListConfig.split(",");
        // 白名单过滤
        for (String str : split) {
            if (keyValue.equals(str)) {
                return jp.proceed();
            }
        }
        // 拦截
        return returnObject(whiteList, method);
    }
    // 返回对象
    private Object returnObject(DoWhiteList whiteList, Method method) throws IllegalAccessException, InstantiationException {
        Class<?> returnType = method.getReturnType();
        // 这里是获取当前标签上的returnJson的数据，也可以全局配置
        String returnJson = whiteList.returnJson();
        if ("".equals(returnJson)) {
            return returnType.newInstance();
        }
        // 返回自定义的配置json
        return JSON.parseObject(returnJson, returnType);
    }
    /**
     * 获取当前的method
     * @param joinPoint
     * @return
     * @throws NoSuchMethodException
     */
    public Method getMethod(ProceedingJoinPoint joinPoint) throws NoSuchMethodException {
        Signature sig =   joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) sig;

        return joinPoint.getTarget().getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes());
    }

    /**
     * 获取属性
     * @param filed
     * @param args
     * @return
     */
    private String getFiledValue(String filed, Object[] args) {
        String filedValue = null;
        for (Object arg : args) {
            try {
                if (null == filedValue || "".equals(filedValue)) {
                    filedValue = BeanUtils.getProperty(arg, filed);
                } else {
                    break;
                }
            } catch (Exception e) {
                if (args.length == 1) {
                    return args[0].toString();
                }
            }
        }
        return filedValue;
    }
}
